<template>
  <div class="dashboard-container">
    <div class="app-container">
      <!-- 通用工具栏组件使用 -->
      <page-tools>
        <!-- 自定义左侧内容 -->
        <template #slot-left>
          <span>共 19 条记录</span>
        </template>

        <!-- 自定义右侧内容 -->
        <template #slot-right>
          <el-button type="danger" size="small" @click="updateBtnFn"
            >导入excel</el-button
          >
          <el-button type="success" size="small" @click="exportBtnFn"
            >导出excel</el-button
          >
          <el-button type="primary" size="small" @click="addEmpShowDialogFn"
            >新增员工</el-button
          >
        </template>
      </page-tools>
      <!-- 表格 -->
      <el-card style="margin-top: 10px;">
        <el-table :data="employeesList" border>
          <el-table-column type="index" label="序号" />
          <el-table-column prop="username" label="姓名" />
          <el-table-column prop="staffPhoto" label="头像" />
          <el-table-column prop="mobile" width="120" label="手机号" />
          <el-table-column
            prop="workNumber"
            label="工号"
            sortable
            :sort-method="workNumberSortFn"
          />
          <!-- 字符串比较
          '1002' '111'比较的时候
          1. 知识: 计算机里,只有0和1,高低电平之分
          比较的时候, 数字直接比较
          字符串/英文 -> 转成ASCII码(二进制)
          2. 字符串比较特点
          从左到右逐位比较大小, 如果比较出大小了就会停止
          每一位取出来 -> ASCII码数字 -> 二进制比较
          a65 A97 048
           -->
          <el-table-column
            prop="formOfEmployment"
            label="聘用形式"
            :formatter="formatter"
          >
            <!-- (1) : 使用插槽技术时, (2) : 需要组件内变量 -> 作用域插槽
            作用域插槽 : 
              (1) : 在组件内, 用<slot 属性名="组件内变量值"></slot>(table-columu写好了内部叫row)
              (2) : 在插槽内, 用template v-slot="变量名" (变量会收集slot身上属性和值形成对象)

            条件表达式(只能用于 true和false, 如果有第三种情况)
             -->
            <!-- 条件表达式和枚举值使用
              条件表达式(只能用于true和false, 如果有第三种值情况)
              枚举适用于, 一个值和多种情况比较, 返回映射的值
              -->
            <template v-slot="scope">
              <!-- <span>{{
                hireTypeList.find(
                  item => item.id === scope.row.formOfEmployment
                ).value
              }}</span> -->
              <span>{{ formatter(scope.row) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="departmentName" label="部门" />
          <el-table-column
            prop="timeOfEntry"
            label="入职时间"
            :formatter="timeFormatter"
          />
          <el-table-column label="操作" width="280">
            <template v-slot="{ row }">
              <el-button
                type="text"
                size="small"
                @click="lookDetailFn(row.id, row.formOfEmployment)"
                >查看</el-button
              >
              <el-button type="text" size="small">分配角色</el-button>
              <el-button
                type="text"
                size="small"
                @click="delEmployee(scope.row)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <el-row type="flex" justify="end" align="middle" style="height: 60px">
          <!-- 分页区域 -->
          <el-pagination
            :current-page="query.page"
            :page-sizes="[10, 15, 20, 25]"
            :page-size="query.size"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </el-row>
      </el-card>
      <!-- 新增列表 -> 弹窗 -->
      <el-dialog title="新增员工" :visible.sync="showDialog" @close="closeFn">
        <emp-form
          :showDialog.sync="showDialog"
          :treeData="treeData"
          @addEmpEV="addEmpFn"
          ref="empForm"
        ></emp-form>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import {
  getEmployeesListAPI,
  getDepartmentsListAPI,
  delEmployeeAPI,
  addEmployeeAPI
} from '@/api'
// 导入回来枚举值
import Employees from '@/api/constant'
// 处理时间格式
// import { parseTime } from '@/utils'
// <!-- 专门处理时间的包 安装dayjs包  npm i dayjs -->
import dayjs from 'dayjs'
import empForm from './components/empForm.vue'
import { transTree } from '@/utils'
export default {
  components: { empForm },
  name: 'Employees',
  data () {
    return {
      query: {
        page: 1, // 页码
        size: 10 // 每页条数
      },
      employeesList: [], // 员工列表
      total: 0, // 数据总条数
      // hireTypeList: Employees.hireType //聘用形式 - 枚举数组
      showDialog: false,
      treeData: [], // 部门列表(树形结构)
      allEmployeesList: [] //所有员工列表
    }
  },
  created () {
    // 获取员工列表
    this.getEmployeesListFn()
    // 获取部门列表
    this.getDepartmentsListFn()
  },
  methods: {
    // 获取员工列表
    async getEmployeesListFn () {
      const res = await getEmployeesListAPI(this.query)
      // console.log(res)
      this.employeesList = res.data.rows //页面表格里当前页码条数得数据
      this.total = res.data.total
      // 第二次请求
      const allRes = await getEmployeesListAPI({
        page: 1,
        // 上一个接口返回后天总数量
        size: res.data.total
      })
      this.allEmployeesList = allRes.data.rows // 这个变量是为了给导出表格使用的
    },
    // 获取部门列表
    async getDepartmentsListFn () {
      const res = await getDepartmentsListAPI()
      this.treeData = transTree(res.data.depts, '')
    },
    // 每页显示的条数发生改变时触发
    handleSizeChange (newSize) {
      // 修改参数对象
      this.query.size = newSize
      // 刷新员工列表
      this.getEmployeesListFn()
    },

    // 当前页面发生改变时触发
    handleCurrentChange (newPage) {
      // console.log(newPage)
      // 修改参数对象
      this.query.page = newPage
      // 刷新员工列表
      this.getEmployeesListFn()
    },
    // 聘用形式 -> 数据处理
    formatter (row) {
      // script 范围内变量Employees, 都可以访问到
      // 传的是字符串格式的, 转为数字
      const obj = Employees.hireType.find(
        item => item.id === parseInt(row.formOfEmployment)
      )
      // 所有obj值为undefined, 返回 '未知'
      return obj ? obj.value : '未知'
    },
    // 处理时间日期格式
    // 时间格式化
    // 后台返回的时间格式不一定是什么?(后端没有做数据的验证,录入新员工不同的同学, 录入的时间格式不同)
    timeFormatter (row) {
      return dayjs(row.timeOfEntry).format('YYYY-MM-DD')
    },
    // 工号 -> 排序方法
    // 数组的sort方法
    // 自定义排序
    workNumberSortFn (a, b) {
      // a和b, 是表格, 对应行数据(可以遍历到数组里所有对象)
      return parseInt(a.workNumber) - parseInt(b.workNumber)
    },
    // 新增点击事件
    addEmpShowDialogFn () {
      this.showDialog = true
    },
    // 删除员工
    async delEmployee (employeesList) {
      const res = await delEmployeeAPI(employeesList.id)
      console.log(res)
      this.$message.success(res.message)
      // 刷新员工列表
      this.getEmployeesListFn()
    },
    // 新增
    async addEmpFn (empObj) {
      await addEmployeeAPI(empObj)
      // console.log(res)
      this.getEmployeesListFn()
    },
    // 新增表单重置
    closeFn () {
      // this -> employees当前组件对象
      // this.$refs.empForm -> empForm组件
      // 对象(好比empForm内this的值)
      // this.$refs.empForm.$refs.addForm -> 就是el-form组件对象了
      this.$refs.empForm.$refs.formData.resetFields()
    },
    // 导入Excel 按钮 -> 点击事件 -> 为了跳转到excel上传页面
    updateBtnFn () {
      this.$router.push('/excel')
    },
    // 导出按钮 -> 点击事件 -> 下载带数据的excel文件(自动)
    exportBtnFn () {
      // import() 方法, webpack提供的一种模块引入的方法 (你也可以写到外卖呢script下)
      // 类似于懒加载, 点击导出按钮的时候, 才去引入对应js
      // import () 方法
      // 参数 : 要引入的包名/路由
      // 返回值 : Promise对象
      import('@/vendor/Export2Excel').then(excel => {
        // excel : 左侧模块导出的对象
        const tHeader = [
          '序号',
          '姓名',
          '头像',
          '手机号',
          '工号',
          '聘用形式',
          '部门',
          '入职时间',
          '转正时间',
          '密码'
        ]
        // const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
        // const list = this.list
        // const data = this.formatJson(filterVal, list)

        // 核心 : 把请求回来数组套对象的数据, 转成只有值得二维数组
        // Object.values() -> 传入对象, 返回所有值得数组
        // 1. 遍历数组里每个对象
        // const newArr = this.employeesList.map(obj => {
        //   // 2. 把对象里所有值收集成数组返回给map, 再装入到大数组里
        //   return Object.values(obj) // ['2018-11-30', '1', '管理员']
        // })
        // const data = newArr

        // 上面问题 : 数据和头部纵向对应不上
        // 原因 : Object.values()取出得值 无序的, 没办法和tHeader按顺序对应
        // 解决 : 想尽一切办法, 让我们的值数组里顺序和tHeader顺序对应上
        // 表格里和页面上列只用到了8个, 而数组里对象有10对key+value
        // 1. 中文 -> 英文的映射关系(枚举值)
        // 序号在遍历的时候, 就有索引值了, 所以它的值不用去英文对象里获取, 所以不用映射
        const zhAndEnObj = {
          姓名: 'username',
          头像: 'staffPhoto',
          手机号: 'mobile',
          工号: 'workNumber',
          聘用形式: 'formOfEmployment',
          部门: 'departmentName',
          入职时间: 'timeOfEntry'
        }
        // 2. 遍历每个英文对象
        const data = this.allEmployeesList.map((enObj, index) => {
          // 3.遍历每个中文key值
          const newArr = [] //保存值
          tHeader.forEach(zhKey => {
            if (zhKey === '序号') {
              newArr.push(index + 1)
            } else {
              const enKey = zhAndEnObj[zhKey]
              const value = enObj[enKey]
              if (enKey === 'formOfEmployment') {
                const obj = Employees.hireType.find(
                  item => item.id === parseInt(value)
                )
                newArr.push(obj ? obj.value : '未知')
              } else {
                newArr.push(value)
              }
            }
          })
          // 4. 把一行值数组return给map内
          return newArr
        })

        // export_json_to_excel() 方法是vendor/Ecport2Excel.js文件内封装的导出excel文件的方法
        excel.export_json_to_excel({
          // 表格文件的列标题(数组)
          header: tHeader,
          // 表格里第二行开始的正文数据(二维数组)
          // 其中内层数组里直接写行的内容值
          data,
          // 导出时excel文件的名字(无需写后缀)
          filename: '文件名',
          // 单元格的宽度自适应
          autoWidth: true,
          // 文件类型
          bookType: 'xlsx'
        })
      })
    },
    // 员工列表 -> 点击查看详情
    lookDetailFn (empId, formOfEmploymentId) {
      this.$router.push(
        `/employees/detail?id=${empId}&form=${formOfEmploymentId}`
      )
    }
  }
}
</script>

<style lang="scss" scoped></style>
